home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-07-18 | 3.3 KB | 72 lines | [TEXT/GEOL] |
- Item 5238380 13-July-89 13:31
-
- From: ROSENSTEIN1 Rosenstein, Larry
-
- To: MACAPP.TECH$ MACAPP Tech
-
- Sub: re More Dispatching
-
- Curtis,
-
- I don't know what other optimizations the linker does. The one you described
- could in fact be done.
-
- The linker can in fact tell whether an instance of TAbstract is created. To
- create an instance of TAbstract you need to refer to TAbstract's method table.
- If there is no such reference, then no instances of TAbstract are created. (If
- there were no subclasses of TAbstract, then the linker would strip out the
- entire class.)
-
- If every subclass of TAbstract overrides DoComputation and no instances of
- TAbstract are created, then TAbstract.DoComputation cannot be called through
- the method dispatcher. The link could remove it from the method table. At
- this point, there are no references to that code, and it would be stripped if
- there is no INHERITED DoComputation call. This is true even if the method
- contained something useful.
-
- (All calls of the form INHERITED xxxx result in direct JSRs to the appropriate
- method. That's the semantics of INHERITED.)
-
- Your suggestions are good ones. C++ allows you to do both of the things you
- describe. You can make the constructor protected, which means it can only be
- called from subclasses. You can also define the implementation of a method
- with '= 0' to indicate that it has no implementation and must be overridden.
-
- I think these are reasonable additions to the language. An important part of
- an o-o language is the mechanisms it provides for describing the type structure
- in your program. In this case, you want to tell users of TAbstract that
- instances of it cannot be created, and that DoComputation must be overridden.
- It is reasonable for a language to allow you to express those things.
-
- Re: your question about AuxiliaryRoutine
-
- If there is a subclass of TAbstract that doesn't override AuxiliaryRoutine,
- then it must still appear in the method tables, because instances of that class
- will inherit that method. If all subclasses override it, then the situtation
- is the same as DoComputation above.
-
- The last thing you mention is really an issue of inline expansion. That is,
- should the compiler inline substitute one procedure body in place of calls to
- that procedure. C++ allows you to advise the compiler when it should expand a
- call inline. Other languages might do this automatically based on heuristics.
-
- There is never any dispatching overhead for an INHERITED call. The semantics
- of INHERITED guarantee that the compiler can know which method to call at
- compiler time. Therefore, the only overhead is that of a procedure call with
- parameters.
-
- As I said above, I really don't know what optimizations the compiler/linker do
- other than the one for monomorphic methods. In theory, the linker can change
- any method call to a direct procedure call if it can figure out the right
- procedure.
-
- For example, suppose x is declared as a TFoo and TFoo has no subclasses. Then
- you can be guaranteed that x is in fact a TFoo object, and I think you can
- statically bind all method calls involving x. Again, I don't know if the
- linker does this optimization, but it should be easy to try out some cases and
- see what the results are.
-
- Larry
-
-
-